package ua.at.tsvetkov.file;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import ua.at.tsvetkov.file.IO;
import ua.at.tsvetkov.util.Log;
import android.os.AsyncTask;
import android.os.Handler;
import android.widget.ProgressBar;

public class AsynkProgressDownloader extends AsyncTask<Object, Integer, Boolean> {

	private ProgressBar	progressBar;
	private Handler		handler;
	private Integer		currentProgress	= 0;
	private boolean		isRunning			= false;
	private int				max = 100;

	/**
	 * Downloads a remote file and stores it locally. execute(Objects) Objects: String - url Remote URL of the file to download String - pathAndFileName Local path with file name where to store the
	 * file Boolean - rewrite If TRUE and file exist - rewrite the file. If FALSE and file exist and his length > 0 - not download and rewrite the file.
	 * 
	 * @param progressBar
	 * @param handler
	 */
	public AsynkProgressDownloader() {
	}

	public void setProgressBar(ProgressBar progressBar) {
		this.progressBar = progressBar;
	}

	public void setMaxProgress(int max) {
		this.max = max;
	}

	public void setHandler(Handler handler) {
		this.handler = handler;
	}

	@Override
	protected Boolean doInBackground(Object... params) {
		String url = (String) params[0];
		String pathAndFileName = (String) params[1];
		boolean rewrite = (Boolean) params[2];
		File f = new File(pathAndFileName);
		int fileSize = 0;
		if (params.length > 3)
			fileSize = (Integer) params[3];
		if (!rewrite && f.exists() && f.length() == fileSize) {
			if (progressBar != null)
				progressBar.setProgress(max);
			Log.v("File exist " + pathAndFileName + " and his size = " + f.length());
			return true;
		}
		Log.i("File exist = " + f.exists() + " and his size = " + f.length() + "(but need " + fileSize + ")");
		if (fileSize == 0)
			fileSize = IO.getFileLength(url);
		if (fileSize == 0)
			return false;
		if (progressBar != null)
			progressBar.setMax(max);
		int partSize = fileSize / max;
		int complete = 0;
		HttpURLConnection conn;
		try {
			conn = (HttpURLConnection) new URL(url).openConnection();
			conn.setDoInput(true);
			conn.setConnectTimeout(IO.TIMEOUT);
			conn.connect();
			int fileLength = conn.getContentLength();
			if (fileLength == 0) {
				Log.i("File length = 0 > " + url);
			}
			InputStream input = conn.getInputStream();
			FileOutputStream fOut = new FileOutputStream(pathAndFileName);
			byte[] buffer = new byte[IO.BUFFER];
			int bytesRead = -1;
			while ((bytesRead = input.read(buffer)) != -1) {
				fOut.write(buffer, 0, bytesRead);
				complete = complete + bytesRead;
				onProgressUpdate(complete / partSize);
				if (isCancelled())
					break;
			}
			fOut.flush();
			fOut.close();
			conn.disconnect();
		} catch (Exception e) {
			Log.w("Download error " + url, e);
			return false;
		}
		return true;
	}

	@Override
	protected void onProgressUpdate(Integer... progress) {
		if (progressBar != null)
			progressBar.setProgress(progress[0]);
		setCurrentProgress(progress[0]);
		Log.i("File progress > " + progress[0]);
	}

	@Override
	protected void onPreExecute() {
		setRunning(true);
		setCurrentProgress(0);
		super.onPreExecute();
	}

	@Override
	protected void onPostExecute(Boolean result) {
		setRunning(false);
		setCurrentProgress(max);
		int what;
		if (result)
			what = 0;
		else
			what = 1;
		if (handler != null)
			handler.sendEmptyMessage(what);
	}

	public Integer getCurrentProgress() {
		return currentProgress;
	}

	public void setCurrentProgress(Integer currentProgress) {
		this.currentProgress = currentProgress;
	}

	public boolean isRunning() {
		return isRunning;
	}

	public void setRunning(boolean isRunning) {
		this.isRunning = isRunning;
	}

}
